package org.openfdtd.core3d;

import java.util.ArrayList;
import java.util.Iterator;
import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Geometry;
import javax.media.j3d.LineArray;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;

/**
 *
 * @author Dorian C. Langbeck
 */
public class Object3D extends SceneComponent implements Iterable<Surface> {
    protected ArrayList<Vertex> vetexes;
    protected TransformGroup objRoot;
    protected Transform3D rotation;
    protected BranchGroup bgRoot;
    protected ObjectStyle style;
    protected Edge[] edges;

    protected Geometry facesGeometry;
    protected LineArray edgesGeometry;
    protected ArrayList<Surface> surfaces;

    public Object3D(Surface[] faces) {
        this(faces, ObjectStyle.DEFAULT_STYLE);
    }

    public Object3D(Surface[] faces, ObjectStyle style) {
        super(true);
        this.style = style;

        rotation = new Transform3D();
        objRoot = new TransformGroup();
        Util.enableWrite(objRoot);
        
        addChild(objRoot);
        objRoot.removeChild(bgRoot);
        bgRoot = new BranchGroup();
        bgRoot.setCapability(BranchGroup.ALLOW_DETACH);

        surfaces = new ArrayList<Surface>(faces.length);
        for (Surface face : faces) {
            surfaces.add(face);
            bgRoot.addChild(face);
        }

        changeAppearance(style.getAppearance());
        objRoot.addChild(bgRoot);
    }

    public ObjectStyle getStyle() {
        return style;
    }

    public void setStyle(ObjectStyle style) {
        this.style = style;
    }

    protected void changeAppearance(Appearance app) {
        Util.changeAppearance(bgRoot, app);
    }

    public void rotate(double x, double y, double z) {
        rotation.rotX(x);
        rotation.rotY(y);
        rotation.rotZ(z);
        objRoot.setTransform(rotation);
    }

    public void rotateX(double rot) {
        rotation.rotX(rot);
        objRoot.setTransform(rotation);
    }

    public void rotateY(double rot) {
        rotation.rotY(rot);
        objRoot.setTransform(rotation);
    }

    public void rotateZ(double rot) {
        rotation.rotZ(rot);
        objRoot.setTransform(rotation);
    }

    public Iterator<Surface> iterator() {
        return surfaces.iterator();
    }
}
